
/**
 * 防抖
 * @param fn 要执行的函数
 * @param delay 延迟时间(毫秒)
 * @returns 防抖后的函数
 */
export function debounce(fn: Function, delay: number):(...args: any) => void {
  let timer: number | null = null

  return function(this: any, ...args: any){
    if(timer) clearTimeout(timer)

    timer = window.setTimeout(()=>{ //window表示浏览器环境，node.js环境下需要使用setTimeout
      fn.apply(this,...args)
      timer = null
    }, delay)
  }
}

/**
 * 节流
 * @param fn 要执行的函数
 * @param delay 延迟时间(毫秒)
 * @returns 节流后的函数
 */
export function throttle(fn: Function, delay: number):(...args: any) => void {
  let timer: number | null = null

  return function(this: any, ...args: any){
    if(timer) return

    timer = window.setTimeout(()=>{
      fn.apply(this,...args)
      timer = null
    }, delay)
  }
}

/**
 * 时间格式化
 * @param date 时间对象或时间戳
 * @param format 格式字符串，支持YYYY/YY/MM/M/DD/D/hh/h/mm/m/ss/s
 * @returns 格式化后的时间字符串
 */
export function formatDate(date: Date | number, format: string): string {
  const d = date instanceof Date ? date : new Date(date); // 确保传入的是Date对象或时间戳
  
  const pad = (num: number, len = 2) => num.toString().padStart(len, '0'); // 补零函数
  
  const tokens: Record<string, string> = {
    YYYY: d.getFullYear().toString(),
    YY: d.getFullYear().toString().slice(-2),
    MM: pad(d.getMonth() + 1),
    M: (d.getMonth() + 1).toString(),
    DD: pad(d.getDate()),
    D: d.getDate().toString(),
    hh: pad(d.getHours()),
    h: d.getHours().toString(),
    mm: pad(d.getMinutes()),
    m: d.getMinutes().toString(),
    ss: pad(d.getSeconds()),
    s: d.getSeconds().toString(),
  };

  return format.replace(
    /Y{2,4}|M{1,2}|D{1,2}|h{1,2}|m{1,2}|s{1,2}/g, 
    (match) => tokens[match] || match
  );
}

/**
 * 文件大小单位转换
 * @param size 文件大小，单位为字节
 * @returns 转换后的文件大小字符串
 */
export function formatFileSize(size: number): string {
  if (typeof size !== 'number' || size <= 0) {
    return '0B' // 处理无效输入或负数
  }

  let value: number, unit: string
  const TB_THRESHOLD = 1024 * 1024 * 1024 * 1024
  const GB_THRESHOLD = 1024 * 1024 * 1024
  const MB_THRESHOLD = 1024 * 1024
  const KB_THRESHOLD = 1024

  if (size >= TB_THRESHOLD) {
    value = size / TB_THRESHOLD
    unit = 'TB'
  } else if (size >= GB_THRESHOLD) {
    value = size / GB_THRESHOLD
    unit = 'GB'
  } else if (size >= MB_THRESHOLD) {
    value = size / MB_THRESHOLD
    unit = 'MB'
  } else if (size >= KB_THRESHOLD) {
    value = size / KB_THRESHOLD
    unit = 'KB'
  } else {
    value = size
    unit = 'B'
  }

  // 处理B的情况直接返回
  if (unit === 'B') {
    return `${value}${unit}`
  }

  // 转换为两位小数并去除末尾的零
  const formattedValue = value.toFixed(2).replace(/\.?0+$/, '')
  return `${formattedValue}${unit}`
}

/**
 * 时长单位转换
 * @param time 时长，单位为s
 * @returns 转换后的时长大小字符串
 */
export function formatTimeSize(time: number): string {
  if (typeof time !== 'number' || time < 0) return '0s'
  let remaining = Math.floor(time) // 向上取整
  if (remaining === 0) return '0s'

  // 带排序的时间单位（从大到小）
  const timeUnits = [
    { value: 3600, suffix: 'h' },
    { value: 60, suffix: 'min' },
    { value: 1, suffix: 's' }
  ]

  // 分解时间单位并动态更新剩余秒数
  const parts = timeUnits.map(unit => {
    const count = Math.floor(remaining / unit.value)
    if (count > 0) {
      remaining -= count * unit.value // 关键修复：更新剩余秒数
      return `${count}${unit.suffix}`
    }
    return null
  }).filter(Boolean) // 过滤掉为null的元素

  return parts.join(' ')
}